package com.xyq.fs.views;

import java.awt.Desktop;
import java.io.File;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.lucene.document.Document;

import com.xyq.fs.constants.FieldConstant;
import com.xyq.fs.constants.ParseConstant;
import com.xyq.fs.contants.filesuffixes2.ExcelEnums;
import com.xyq.fs.contants.filesuffixes2.PdfEnums;
import com.xyq.fs.contants.filesuffixes2.PptEnums;
import com.xyq.fs.contants.filesuffixes2.TxtEnums;
import com.xyq.fs.contants.filesuffixes2.WordEnums;
import com.xyq.fs.entity.MyFile;
import com.xyq.fs.index.IndexFileInf;
import com.xyq.fs.search.SearchBody;

import com.xyq.fs.util.MyFilesUtil;
import com.xyq.fs.util.MyHighLight;

import javafx.application.Platform;
import javafx.beans.InvalidationListener;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.JFXPanel;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;

import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.stage.FileChooser;
import javafx.stage.Stage;
import javafx.util.Callback;

@SuppressWarnings("unchecked")
public class UIutil {

	private SearchBody body;

	public UIutil(SearchBody body) {

		this.body = body;

	}
	public Text t1 = new Text();
	public static String SYSTEM_ROOT = System.getProperty("user.dir") + "\\CONF\\BACKUP\\";
	public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	public static FileChooser fileChooser = new FileChooser();
	public static Desktop desk = Desktop.getDesktop();
	public static Map<String, MyFile> cacheMyFile = new HashMap<>();

	public Group root = new Group();

	public Scene scene = new Scene(root, 682, 550);

	public Stage stage = new Stage();

	private static Map<String, WindowsC> cmap = new HashMap<String, WindowsC>();

	public Button btnNext = new Button("下一页");
	public Button btnPre = new Button("上一页");
	public Button BtnC = new Button("当前页: 1");

	public TableView<MyData> tableView = new TableView<MyData>();
	public ObservableList<MyData> dataa = FXCollections.observableArrayList();
	// 绑定文件名
	public TableColumn<MyData, TextFlow> nameCol = new TableColumn<MyData, TextFlow>("文件名");
	// 绑定文件预览按钮
	public TableColumn<MyData, Button> seeCol = new TableColumn<MyData, Button>("内容预览");
	// 绑定访问目录按钮
	public TableColumn<MyData, Button> dirCol = new TableColumn<MyData, Button>("访问目录");
	// 绑定复制文件按钮
	public TableColumn<MyData, Button> cpoyCol = new TableColumn<MyData, Button>("复制文件");
	// 绑定笔记文件按钮
	// public TableColumn<MyData, Button> bzCol = new TableColumn<MyData,
	// Button>("文件笔记");
	public HBox hBox2 = new HBox();
	public VBox vBox = new VBox();
	// public ProgressIndicator pinA = new ProgressIndicator();
	// private Label labelA = new Label("正在查询中,请稍后...");
	private WindowsC WC = new WindowsC();
	private Stage wcState = new Stage();
	private Stage dirState = new Stage();

	public Text currentPageNumText = new Text("当前页:  ");

	{
		tableView.getColumns().addAll(nameCol, seeCol, dirCol, cpoyCol);
		tableView.setStyle("-fx-opacity: 0.74;");
		tableView.setItems(dataa);
		stage.setScene(scene);
		Platform.runLater(() -> {
			WC.start(wcState);
		});

		currentPageNumText.setId("txt");
		currentPageNumText.setFill(Color.WHITE);
		currentPageNumText.setFont(new Font("微软雅黑", 15));
		currentPageNumText.setStyle("-fx-text-alignment:center;");

	}

	public Map<Integer, MyData> myDataMap = new HashMap<>();

	static String btnStr = WindowsB.class.getResource("WindowsB.css").toExternalForm();

	{

		BtnC.setId("btnc");
		btnPre.setId("btna");
		btnNext.setId("btna");
		root.getChildren().add(new ImageView(WindowsGo.imageA));
		scene.setCursor(WindowsGo.Mouse);
		btnNext.getStylesheets().add(btnStr);
		btnPre.getStylesheets().add(btnStr);
		btnNext.setPrefSize(85, 31);
		btnPre.setPrefSize(85, 31);
		BtnC.getStylesheets().add(btnStr);
		BtnC.setPrefSize(180, 31);

		tableView.setStyle("-fx-font-family: '微软雅黑';");
		tableView.getStylesheets().add(btnStr);
		tableView.setMinHeight(400);
		tableView.setTranslateX(0);

		tableView.setVisible(false);

		tableView.setId("tbv");
		nameCol.setStyle("-fx-font-family: '微软雅黑';");
		nameCol.setMinWidth(479);
		nameCol.setCellValueFactory(new Callback<CellDataFeatures<MyData, TextFlow>, ObservableValue<TextFlow>>() {
			public ObservableValue<TextFlow> call(CellDataFeatures<MyData, TextFlow> p) {
				return p.getValue().getFileName();
			}
		});

		seeCol.setStyle("-fx-font-family: '微软雅黑';");
		seeCol.setMaxWidth(72);
		seeCol.setMinWidth(72);
		seeCol.setCellValueFactory(new Callback<CellDataFeatures<MyData, Button>, ObservableValue<Button>>() {
			public ObservableValue<Button> call(CellDataFeatures<MyData, Button> p) {
				return p.getValue().getSeeBtn();
			}
		});

		dirCol.setMaxWidth(72);
		dirCol.setMinWidth(72);
		dirCol.setStyle("-fx-font-family: '微软雅黑';");
		dirCol.setCellValueFactory(new Callback<CellDataFeatures<MyData, Button>, ObservableValue<Button>>() {
			public ObservableValue<Button> call(CellDataFeatures<MyData, Button> p) {
				return p.getValue().getDirBtn();
			}
		});
		

		cpoyCol.setMaxWidth(72);
		cpoyCol.setMinWidth(72);
		cpoyCol.setStyle("-fx-font-family: '微软雅黑';");
		cpoyCol.setCellValueFactory(new Callback<CellDataFeatures<MyData, Button>, ObservableValue<Button>>() {
			public ObservableValue<Button> call(CellDataFeatures<MyData, Button> p) {
				return p.getValue().getCopyBtn();
			}
		});


		root.getChildren().add(vBox);
	}

	public TextFlow tff = new TextFlow();

	{
		// Pos.TOP_LEFT;
		// pinA.setTranslateX(-40);
		// pinA.setPrefSize(35, 35);
		// labelA.setTranslateX(310);
		// vBox.getChildren().addAll(hBox2, tff, pinA, labelA, tableView);
		vBox.getChildren().addAll(hBox2, tff, tableView);
		// labelA.setStyle("-fx-font-family: \"微软雅黑\";");
		// labelA.setStyle("-fx-font-size: 19px;");
		// labelA.setStyle("-fx-text-fill: #CDC5BF;");

		vBox.setMinHeight(500);
		vBox.setSpacing(20);
		hBox2.setPadding(new Insets(30, 10, -10, 23));
		hBox2.getChildren().addAll(btnPre, new Text("    "), btnNext, BtnC);

	}

	

	{

		t1.setId("scanTs");
		t1.setFont(new Font("微软雅黑", 17));
		t1.setFill(Color.valueOf("#CDC5BF"));

		tff = new TextFlow(t1);
		tff.setPadding(new Insets(10.5, 17.5, 0, 23));
		vBox.getChildren().set(1, tff);

	}

	public static Map<String, TextFlow> tfMap = new HashMap<String, TextFlow>();
	public static Map<Document, Path> docMap = new HashMap<Document, Path>();

	/**
	 * 页面绑定类
	 * 
	 * @author xyq
	 *
	 */
	public class MyData {

		private TextFlow tf;
		private ObservableValue<Button> dirBtn;
		private ObservableValue<Button> copyBtn;
		private ObservableValue<Button> seeBtn;
		private ObservableValue<TextFlow> fileName;
		// private String simpleFilePath;
		private ObservableValue<Button> bzBtn;
		public Document docc;
		public Path pathNow;
		// public Path path2;

		public Document getDoc() {

			return docc;
		}

		public void setDoc(Document doc) {

			init(doc);

		}

		public ObservableValue<Button> getBzBtn() {

			return bzBtn;
		}

		public void setBzBtn(ObservableValue<Button> bzBtn) {
			this.bzBtn = bzBtn;
		}

		private void init(Document doc) {

			docc = doc;
			Path path2 = docMap.get(docc);
			if (path2 == null) {
				path2 = Paths.get(docc.get(FieldConstant.FILE_PATH));
				docMap.put(docc, path2);
			}
			pathNow = path2;
			String str = pathNow + body.getSearchKey();
			TextFlow tf2 = tfMap.get(str);
			if (tf2 == null) {
				tf2 = high2(docc.get(FieldConstant.FILE_NAME), body.getSearchKeys(), pathNow.getParent().toString(),
						doc.get(FieldConstant.FILE_UPDATE_TIME));
				tfMap.put(str, tf2);
				tf2.setPrefHeight(68);
			}
			this.tf = tf2;

		}

		public MyData(Document doc) {

			init(doc);
			// 行高

			this.fileName = new ObservableValue<TextFlow>() {

				@Override
				public void removeListener(InvalidationListener arg0) {
				}

				@Override
				public void addListener(InvalidationListener arg0) {
				}

				@Override
				public void removeListener(ChangeListener<? super TextFlow> listener) {
				}

				@Override
				public TextFlow getValue() {

					return tf;
				}

				@Override
				public void addListener(ChangeListener<? super TextFlow> listener) {
				}
			};

			this.dirBtn = new ObservableValue<Button>() {
				@Override
				public void addListener(InvalidationListener listener) {
				}

				@Override
				public void removeListener(InvalidationListener listener) {
				}

				@Override
				public void addListener(ChangeListener<? super Button> listener) {
				}

				@Override
				public void removeListener(ChangeListener<? super Button> listener) {
				}

				@Override
				public Button getValue() {
					Button btn = new Button("查看目录");
					btn.setId("teshu");
					btn.setOnAction(new EventHandler<ActionEvent>() {
						@Override
						public void handle(ActionEvent event) {

							openDir(pathNow);
						}
					});
					return btn;
				}
			};

			this.seeBtn = new ObservableValue<Button>() {

				@Override
				public void addListener(InvalidationListener listener) {
				}

				@Override
				public void removeListener(InvalidationListener listener) {
				}

				@Override
				public void addListener(ChangeListener<? super Button> listener) {
				}

				@Override
				public void removeListener(ChangeListener<? super Button> listener) {
				}

				@Override
				public Button getValue() {

					Button btn = new Button("内容预览");
					btn.setId("teshu");

					btn.setOnAction(new EventHandler<ActionEvent>() {
						@Override
						public void handle(ActionEvent event) {

							if (!Files.exists(pathNow)) {
								MyAlert.alertError("抱歉,文件未找到!!!");
							} else {
								WindowsC wcc = cmap.get(pathNow.toString() + body.getSearchKey());
								if (wcc != null) {
									wcc.show2();
								} else {
									WC.setPath(pathNow);
									WC.show();
									cmap.put(pathNow.toString() + body.getSearchKey(), WC);
									WC = new WindowsC();
									wcState = new Stage();
									WC.start(wcState);
								}
							}
						}
					});
					return btn;
				}
			};

			this.copyBtn = new ObservableValue<Button>() {
				@Override
				public void removeListener(InvalidationListener listener) {
				}

				@Override
				public void addListener(InvalidationListener listener) {
				}

				@Override
				public void removeListener(ChangeListener<? super Button> listener) {
				}

				@Override
				public Button getValue() {
					Button btn = new Button("复制文件");
					btn.setId("teshu");
					btn.setOnAction(new EventHandler<ActionEvent>() {
						@Override
						public void handle(ActionEvent event) {

							// 0表示原来的，1表示现在的，2表示都没有

							if (!Files.exists(pathNow)) {
								MyAlert.alertError("文件未找到");
							} else {
								try {
									new MyFilesUtil().copeFile((pathNow).toString());
									MyAlert.alert("文件已复制");
									// JOptionPane.showMessageDialog(null,
									// "复制文件成功");
								} catch (Exception e) {
									MyAlert.alertError("文件复制失败");
								}
							}
						}
					});
					return btn;
				}

				@Override
				public void addListener(ChangeListener<? super Button> listener) {

				}
			};

		}

		public ObservableValue<TextFlow> getFileName() {

			return fileName;
		}

		public void setFileName(ObservableValue<TextFlow> fileName) {
			this.fileName = fileName;
		}

		public ObservableValue<Button> getDirBtn() {
			return dirBtn;
		}

		public void setDirBtn(ObservableValue<Button> dirBtn) {
			this.dirBtn = dirBtn;
		}

		public ObservableValue<Button> getCopyBtn() {
			return copyBtn;
		}

		public void setCopyBtn(ObservableValue<Button> copyBtn) {
			this.copyBtn = copyBtn;
		}

		public TextFlow getTf() {
			return tf;
		}

		public void setTf(TextFlow tf) {
			this.tf = tf;
		}

		public ObservableValue<Button> getSeeBtn() {
			return seeBtn;
		}

		public void setSeeBtn(ObservableValue<Button> seeBtn) {
			this.seeBtn = seeBtn;
		}

	}

	static Font hFont = Font.font("微软雅黑", FontWeight.BOLD, 14);

	public static TextFlow high2(String str, String[] keys, String path, String updateTime) {

		
		List<Text> txtList = new ArrayList<>();
		Text t;
		Set<Character> set = new HashSet<>();
		for (String key : keys) {
			// 关键词转化为小写
			for (int i = 0; i < key.length(); i++)
				set.add(key.charAt(i));
		}
		// 标红的开头和结尾
		int s = -1;
		// 普通的开头和结尾
		int ss = -1;
		
		String str2 = str.toLowerCase();
		for (int i = 0; i < str.length(); i++) {
			char c = str2.charAt(i);
			if (set.contains(c)) {
				// 如果是开头
				if (s == -1) {
					s = i;
				}
				if (ss != -1) {
					t = new Text(str.substring(ss, i));
					t.setFont(hFont);
					ss = -1;
					txtList.add(t);
				}
			} else {
				// 如果此时有开头结尾，就要把红的装起来
				if (s != -1) {
					t = new Text(str.substring(s, i));
					t.setFill(Color.RED);
					t.setFont(hFont);
					s = -1;
					txtList.add(t);
				}
				if (ss == -1) {
					ss = i;
				}
			}
		}
		if (ss != -1) {
			t = new Text(str.substring(ss));
			t.setFont(hFont);
			txtList.add(t);
		}
		if (s != -1) {
			t = new Text(str.substring(s));
			t.setFont(hFont);
			t.setFill(Color.RED);
			txtList.add(t);
		}
		t = new Text("\n" + path);
		txtList.add(t);
		t = new Text("\n" + "(" + sdf.format(new Date(Long.parseLong(updateTime))) + ")");
		txtList.add(t);
		Text[] tar = {};
		str2 = null;
		str = null;
		TextFlow tf = new TextFlow(txtList.toArray(tar));
		return tf;
	}

	public void openDir(Path path) {

		Platform.runLater(() -> {

			if (!Files.exists(path)) {
				MyAlert.alertError("抱歉,文件未找到!!!");
			} else {
				fileChooser.setInitialDirectory(path.getParent().toFile());
				File file = fileChooser.showOpenDialog(dirState);
				try {
					desk.open(file);
				} catch (Exception e) {
				} finally {
					dirState = new Stage();
				}
			}
		});
	}

	/**
	 * 高亮算法
	 * 
	 * @param str
	 * @param key
	 * @return
	 */

	public String yuLanFile(Path path) {

		String fname = path.getFileName().toString().toUpperCase();
		IndexFileInf iff = null;
		if (TxtEnums.suffixContains(fname)) {
			iff = ParseConstant.itf;
		} else if (fname.endsWith(PdfEnums.PDF)) {
			iff = ParseConstant.ipf;
		} else if (PptEnums.suffixContains(fname)) {
			iff = ParseConstant.ippf;
		} else if (WordEnums.suffixContains(fname)) {
			iff = ParseConstant.iwf;
		} else if (ExcelEnums.suffixContains(fname)) {
			iff = ParseConstant.ief;
		}
		if (iff != null)
			return MyHighLight.high(iff.getContent(path.toFile(), fname), body.getSearchKeys(),
					"<span style=\"color:red\">", "</span>");
		return "抱歉,非可读文件的内容暂时不可预览!!!";
	}

	public MyData getMyData(Document doc) {

		return new MyData(doc);
	}

	public static void main(String[] args) {
		new JFXPanel();
		String str = "中盐江西.txt";
		TextFlow tf = high2(str, new String[] { ".txt" }, null, null);
		tf.getChildren().forEach(txt -> {
			System.out.println(txt);
		});
	}
}
